#ifndef __BOUNDING_BOX_HPP__
#define __BOUNDING_BOX_HPP__

#include "Vector3.hpp"

namespace PocketSurvival::Engine
{
    struct BoundingBox
    {
        Vector3 Min;
        Vector3 Max;

        constexpr BoundingBox() noexcept;
        constexpr BoundingBox(const Vector3 &min, const Vector3 &max) noexcept;
        constexpr BoundingBox(float x1, float y1, float z1, float x2, float y2, float z2) noexcept;

        constexpr inline Vector3 center();
        constexpr inline Vector3 size();
        constexpr inline float volume();
        constexpr inline bool contains(const Vector3 &vec) noexcept;
        constexpr inline bool intersection(const BoundingBox& box) const;

        friend constexpr inline bool operator==(const BoundingBox &left, const BoundingBox &right)
        {
            return (left.Min == right.Min) && (left.Max == right.Max);
        }
        friend constexpr inline bool operator!=(const BoundingBox &left, const BoundingBox &right)
        {
            return !(left == right);
        }
    };

    constexpr inline BoundingBox::BoundingBox() noexcept {}
    constexpr inline BoundingBox::BoundingBox(const Vector3 &min, const Vector3 &max) noexcept : Min(min), Max(max) {}
    constexpr inline BoundingBox::BoundingBox(float x1, float y1, float z1, float x2, float y2, float z2) noexcept : Min(x1, y1, z1), Max(x2, y2, z2) {}

    constexpr inline Vector3 BoundingBox::center()
    {
        return Vector3(0.5f * (Max.posX + Min.posX), 0.5f * (Max.posY + Min.posY), 0.5f * (Max.posZ + Min.posZ));
    }
    constexpr inline Vector3 BoundingBox::size()
    {
        return Max - Min;
    }
    constexpr inline float BoundingBox::volume()
    {
        return size().volume();
    }

    constexpr inline bool BoundingBox::contains(const Vector3& vec) noexcept
    {
        return  (vec.posX >= Min.posX && vec.posX <= Max.posX) && 
                (vec.posY >= Min.posY && vec.posY <= Max.posY) && 
                (vec.posZ >= Min.posZ && vec.posZ <= Max.posZ);
    }

    constexpr inline bool BoundingBox::intersection(const BoundingBox& box) const
    {
        return  (box.Max.posX >= Min.posX && box.Min.posX <= Max.posX) &&
                (box.Max.posY >= Min.posY && box.Min.posY <= Max.posY) &&
                (box.Max.posZ >= Min.posZ && box.Min.posZ <= Max.posZ);
    }

    

}

#endif